package com.niiwoo.civet.trade.service.local.invest;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.niiwoo.activity.stage.dto.request.prize.ActivityInvestCashbackReqDTO;
import com.niiwoo.activity.stage.dto.request.prize.ActivityInvestRatesReqDTO;
import com.niiwoo.activity.stage.dto.request.prize.ActivityNewInvestRatesReqDTO;
import com.niiwoo.activity.stage.dto.request.prize.ActivityPrizeQueryReqDTO;
import com.niiwoo.activity.stage.dto.response.prize.UserPrizeResponseDTO;
import com.niiwoo.activity.stage.enums.prize.DeadLineUnitEnum;
import com.niiwoo.activity.stage.enums.prize.UserPrizeSuitProjectTypeEnum;
import com.niiwoo.activity.stage.enums.prize.UserPrizeTypeIdEnum;
import com.niiwoo.activity.stage.service.prize.ActivityPrizeDubboService;
import com.niiwoo.civet.base.enums.DeadlineUnitEnum;
import com.niiwoo.civet.trade.dao.entity.ProjectInvesting;
import com.niiwoo.civet.trade.enums.ProjectTypeEnum;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;

import lombok.extern.slf4j.Slf4j;

/**
 * Created by zhangwanli on 2018/4/25.
 */
@Service
@Slf4j
public class InvestPrizeService {

    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;

    @Reference(version = "1.0.0")
    private ActivityPrizeDubboService activityPrizeDubboService;

    /**
     * 从活动服务查询合适的红包
     *
     * @param userId       用户ID
     * @param project      投资中标的
     * @param investAmount 投资金额
     * @param prizeConfig  投资红包配置
     * @return 红包id，没有则为null
     */
    public Long querySuitablePrize(String userId, ProjectInvesting project, BigDecimal investAmount, BigDecimal useCouponMinInvestAmount) {
        ProjectTypeEnum typeEnum = ProjectTypeEnum.getEnum(project.getType());
        if (!projectSupportPrize(project)) {
            log.info("该标的不满足红包使用规则,type={},deadlineUnit={}", project.getType(), project.getDeadlineUnit());
            return null;
        }
        UserPrizeSuitProjectTypeEnum prizeProjectType = mappingActivityPrizeProjectType(typeEnum);
        DeadLineUnitEnum deadLineUnit = mappingActivityPrizeProjectDeadline(project.getDeadlineUnit());
        Long projectId = project.getProjectId();
        Long prizeId = null;
        try {
            log.info("查询活动投资返现红包,userId={},projectId={}", userId, projectId);
            ActivityInvestCashbackReqDTO reqDTO = new ActivityInvestCashbackReqDTO();
            reqDTO.setOrderNo(snowflakeIdWorker.nextId());
            reqDTO.setUserId(userId);
            reqDTO.setProjectId(projectId);
            reqDTO.setDeadLineUnitEnum(deadLineUnit);
            reqDTO.setDeadLine(project.getDeadline());
            reqDTO.setAmount(investAmount);
            reqDTO.setSuitProjectTypeEnum(prizeProjectType);
            prizeId = activityPrizeDubboService.getInvestCashbackPrize(reqDTO);
            if (prizeId == null) {
                log.info("未查询到活动投资返现红包,userId={},projectId={}", userId, projectId);
            }
        } catch (Exception e) {
            log.error("查询合适的可用投资返现红包出错", e);
        }
        if (prizeId == null && investAmount.compareTo(useCouponMinInvestAmount) >= 0) {
            log.info("查询活动投资加息券,userId={},projectId={}", userId, projectId);
            ActivityNewInvestRatesReqDTO reqDTO = new ActivityNewInvestRatesReqDTO();
            reqDTO.setOrderNo(snowflakeIdWorker.nextId());
            reqDTO.setUserId(userId);
            reqDTO.setProjectId(projectId);
            reqDTO.setAmount(investAmount);
            reqDTO.setDeadLineUnitEnum(Byte.valueOf("1").equals(project.getDeadlineUnit())?DeadLineUnitEnum.DAY:DeadLineUnitEnum.MONTH);
            reqDTO.setDeadLine(project.getDeadline());
            reqDTO.setSuitProjectTypeEnum(prizeProjectType);
            
            try {
                prizeId = activityPrizeDubboService.getNewInvestRaisePrize(reqDTO);
                if (prizeId == null) {
                    log.info("未查询到活动投资加息券,userId={},projectId={}", userId, projectId);
                }
            } catch (Exception e) {
                log.error("查询合适的可用投资加息券出错", e);
            }
        } else {
            log.info("未查询到活动投资返现红包,投资金额不满足加息券使用规则,不查询投资加息券,userId={},projectId={}", userId, projectId);
        }
        return prizeId;
    }

    public boolean projectSupportPrize(ProjectInvesting project) {
        return mappingActivityPrizeProjectType(ProjectTypeEnum.getEnum(project.getType())) != null
                && mappingActivityPrizeProjectDeadline(project.getDeadlineUnit()) != null;
    }

    /**
     * 业务标的类型映射到活动红包支持的标的类型
     *
     * @param type 业务标的类型
     * @return 对应活动红包支持的标的类型
     */
    private UserPrizeSuitProjectTypeEnum mappingActivityPrizeProjectType(ProjectTypeEnum type) {
        Integer userPrizeSuitProjectType = type.getUserPrizeSuitProjectType();
        UserPrizeSuitProjectTypeEnum typeEnum = null;
        try {
            typeEnum = UserPrizeSuitProjectTypeEnum.getTypeEnum(userPrizeSuitProjectType);
            if (UserPrizeSuitProjectTypeEnum.FORBID == typeEnum) {
                log.warn("prize forbid for this project type:{}", type);
                return null;
            }
        } catch (Exception e) {
            log.error("mapping prize project type error", e);
        }
        return typeEnum;
    }

    private DeadLineUnitEnum mappingActivityPrizeProjectDeadline(Byte deadlineUnit) {
        if (DeadlineUnitEnum.BY_MONTH.getDeadlineUnit().equals(deadlineUnit)) {
            return DeadLineUnitEnum.MONTH;
        }
        if (DeadlineUnitEnum.BY_DAY.getDeadlineUnit().equals(deadlineUnit)) {
            return DeadLineUnitEnum.DAY;
        }
        log.warn("红包活动不支持该投资期限标的:{}", deadlineUnit);
        return null;
    }
    /**
     * 验证可用余额是否可以使用红包
     * @param investorId
     * @param useCouponMinInvestAmount
     * @param availableAmount
     * @return
     */
	public boolean valdatePrize(String investorId, BigDecimal useCouponMinInvestAmount, BigDecimal availableAmount) {
		ActivityPrizeQueryReqDTO requestDTO = new ActivityPrizeQueryReqDTO();
		requestDTO.setUserId(investorId);
		List<UserPrizeTypeIdEnum> enums = new ArrayList<>();
		requestDTO.setPrizeTypeIdEnums(enums);
		enums.add(UserPrizeTypeIdEnum.INVESTMENT_RAISE_INTEREST_RATES);//投资加息券
		enums.add(UserPrizeTypeIdEnum.INVESTMENT_CASHBACK);//返现红包
		
		List<UserPrizeResponseDTO> prizes =  activityPrizeDubboService.getUserPrizeByCondition(requestDTO);
		//没有红包或者加息券
		if(CollectionUtils.isEmpty(prizes)) {
			return false;
		}
		BigDecimal redPrizeMinAmount = BigDecimal.valueOf(Integer.MAX_VALUE);
		boolean hasAvailablePrize = false;//是否有可用红包或加息券
//		availableAmount = availableAmount.subtract(useCouponMinInvestAmount);//最低可用金额
		BigDecimal addRateMinAmount = BigDecimal.valueOf(Integer.MAX_VALUE);
		for (UserPrizeResponseDTO userPrizeResponseDTO : prizes) {
			//存在可用红包或加息券
			if(Byte.valueOf("0").equals(userPrizeResponseDTO.getIsUsed())) {
				hasAvailablePrize = true;
			}
			//存在返现红包，获取红包最低使用金额
			if(UserPrizeTypeIdEnum.INVESTMENT_CASHBACK.getPrizeType().equals(userPrizeResponseDTO.getPrizeTypeId())) {
				redPrizeMinAmount = redPrizeMinAmount.min(userPrizeResponseDTO.getMinSuitProjectAmount());
				continue;
			}
			//存在加息券
			if(UserPrizeTypeIdEnum.INVESTMENT_RAISE_INTEREST_RATES.getPrizeType().equals(userPrizeResponseDTO.getPrizeTypeId())) {
				addRateMinAmount = addRateMinAmount.min(userPrizeResponseDTO.getMinSuitProjectAmount());
			}
		}
		log.info("自动投资红包校验,用户{},红包最低使用金额{},加息券最低使用金额{},余额{},自动投资加息券最低使用金额{}",investorId,redPrizeMinAmount,addRateMinAmount,availableAmount,useCouponMinInvestAmount);
		//无可用红包
		if(!hasAvailablePrize) {
			return false;
		}
		// 可用余额大于返现红包最低可用金额或者 可用余额大于加息券最大使用金额并且大于字段配置使用红包设置金额
		if(availableAmount.compareTo(redPrizeMinAmount)>0 || (availableAmount.compareTo(addRateMinAmount)>0&&availableAmount.compareTo(useCouponMinInvestAmount)>0)) {
			return true;
		}
		
		return false;
	}
    
    
    
    
    
}
